// 编辑报表
import React, { useEffect, useState } from 'react';
import styles from './index.module.scss';
import { message } from 'antd';
import PageEditor from 'src/pages/AnalyseManage/EditReport/components/Page/Editor';
import Page from 'src/pages/AnalyseManage/EditReport/components/Page';
import EditorTop from './EditReportTop';
import EditorRight from './EditReportRight';
import ChartsDragContainer from 'src/pages/AnalyseManage/EditReport/components/ChartsDragContainer';
import PreviewTop from './components/PreviewTop';
import { defaultStyles, defaultDataConfigs, FILTER_MENU } from './DefaultConfig';
import { DoubleRightOutlined, DoubleLeftOutlined } from '@ant-design/icons';

const EditReportIndex = ( props: any ) => {
	const { pageContentConfig, saveConfig, onValuesChange, pageId, tenantCode = '' } = props;

	const [ currentType, setCurrentType ] = useState( pageContentConfig.page.type ); // 报表类型，如page/text
	const [ currentKey, setCurrentKey ] = useState();
	const [ currentConf, setCurrentConf ] = useState( { key: null, data: null } );
	const [ hiddenControlPanel, setHiddenControlPanel ] = useState( false );
	const [ showControlPanel, setShowControlPanel ] = useState( true );
	const [ controlPanelWidth, setControlPanelWidth ] = useState( 380 );
	// const [ pos, setPos ] = useState( { x: 0, y: 0, w: 350 } );
	const [ dragging, setDragging ] = useState( false );
	let pos = { x: 0, y: 0, w: 380, dragging: false };
	// let dragging = false;

	//	拖拽之后的回调
	const handleLayoutConfChange = ( layoutConfig ) => {
		const newPageContentConfig = Object.assign( {}, pageContentConfig, {
			layoutConfig: layoutConfig,
		} );
		onValuesChange( newPageContentConfig );
	};

	const handelSaveConfig = async () => {
		if ( pageContentConfig ) {
			saveConfig( pageContentConfig );
		}
	};

	//	判断是否是编辑标题, 'Page'是为了兼容老数据
	const isPage = ( type ) => {
		return type === 'report' || type === 'dashboard' || type === 'Page';
	};

	/**
	 *
	 * @param chartType 样式类型, 如page,table,text
	 * @param key 唯一标识
	 * @param values 更改的对象
	 * @param configType 配置到对应的对象里面, 如style,data,mutual
	 */
	const handelValuesChange = ( chartType: string, key: string, values: Object, configType?: string ) => {
		let { page, children = [] } = pageContentConfig;

		if ( !isPage( chartType ) ) {
			children = children.map( ( t ) => {
				if ( t.key === key ) {
					const newConfig = {
						...t,
						[configType]: { ...t[configType], ...values },
					};
					if( Object.keys( currentConf ).length && key === currentConf.key ) {
						setCurrentConf( newConfig );
					}

					return newConfig;
				} else {
					return t;
				}

			} );
		} else {
			page = { ...page, ...values };
		}
		let newPageContentConfig = { ...pageContentConfig, page, children };
		if ( onValuesChange ) {
			onValuesChange( newPageContentConfig );
		}
	};

	const handelAllValuesChange = ( values, pageConf?: {} ) => {
		let { page } = pageContentConfig;
		page = { ...page, ...pageConf };
		let newPageContentConfig = { ...pageContentConfig, page, children: values };

		if ( onValuesChange ) {
			onValuesChange( newPageContentConfig );
		}
	};

	const onSelect = ( config: any ) => {
		if ( !props.isEdit ) return;
		setCurrentKey( config.key );
		setCurrentType( config.type );
		setCurrentConf( config );
	};

	//	新添加的组件，获取y轴最大值
	const getMaxY = ( layoutConfig ) => {
		if ( layoutConfig.length === 0 ) return 0;
		let maxY = 0;

		layoutConfig.forEach( ( v ) => {
			maxY = v.y + v.h > maxY ? v.y + v.h : maxY;
		} );
		return maxY;
	};

	const addComponent = ( config, copyKey = '' ) => {
		// console.log( config );
		let { children = [] } = pageContentConfig;
		const newChildren = Array.from( children );
		newChildren.push( config );
		//	添加layout, 如果是复制，就找到复制源，然后设置位置相对偏移
		let newComponentLayout;
		if ( copyKey ) {
			let copyLayout = props.pageContentConfig.layoutConfig.find( ( v ) => v.i === copyKey );
			newComponentLayout = Object.assign( {}, copyLayout, {
				i: config.key,
				x: copyLayout.x + 2,
				y: copyLayout.y + 2,
			} );
		} else {
			let size = { w: 17, h: 18 };
			newComponentLayout = {
				i: config.key,
				x: 0,
				y: getMaxY( props.pageContentConfig.layoutConfig ),
				...size,
			};
		}
		let layoutConfig = [ ...props.pageContentConfig.layoutConfig, newComponentLayout ];

		//	设置新添加的组件为当前选中
		onSelect( config );

		let newPageContentConfig = { ...pageContentConfig, children: newChildren, layoutConfig };
		if ( onValuesChange ) {
			onValuesChange( newPageContentConfig );
		}
	};

	//	复制单个图表，layout需要相对复制源偏移，key需要新建
	const handleCopyItem = ( item ) => {
		const newItem = Object.assign( {}, item, { key: `${new Date().getTime()}` } );
		addComponent( newItem, item.key );
	};

	//	保存单个图表 
	// const handleSaveyItem = ( item ) => {
	// };

	const addChart = ( type ) => {
		console.log( '== currentConf ===', currentConf );
		let key = `${new Date().getTime()}`;
		let data = defaultDataConfigs[type] || {};
		// 保持前一个图表的数据选项
		if ( currentConf && currentConf.data && currentConf.data.tableCode ) {
			data.tableCode = currentConf.data.tableCode;
		}
		addComponent( {
			key: key,
			type: type.split( '_' )[ 0 ],
			style: defaultStyles[type] || {},
			data,
			mutual: {},
		} );
		message.success( `${defaultStyles[type].titleValue} 已添加` );
	};

	//	判断是否是筛选组件
	const isFilterChart = ( chartType ) => {
		return FILTER_MENU.some( v => v.type === chartType );
	};

	//	删除图表
	const handleDelete = ( key: string ) => {

		let newChildren;
		let { children = [], layoutConfig = [] } = pageContentConfig;
		newChildren = JSON.parse( JSON.stringify( children ) );		//	需要深拷贝

		const deleteItem = newChildren.splice(
			newChildren.findIndex( ( v ) => v.key === key ),
			1
		)[0];

		layoutConfig.splice(
			layoutConfig.findIndex( ( v ) => v.i === key ),
			1
		);

		//	如果是删除的筛选组件，则判断其他组件的筛选条件是否包含被删除的组件，如果包含，则清除
		if( isFilterChart( deleteItem.type ) ) {
			newChildren = newChildren.map( v => {
				let filterConditions = v.data.filterConditions;
				if( filterConditions && filterConditions[deleteItem.key] ) {
					delete filterConditions[deleteItem.key];
				}
				return { ...v, data: { ...v.data, filterConditions } };
			} );

		}

		const newPageContentConfig = { ...pageContentConfig, children: newChildren, layoutConfig };
		if ( onValuesChange ) {
			onValuesChange( newPageContentConfig );
		}

		//	删除之后，把光标指向标题框
		onSelect( pageContentConfig.page );
	};

	const handleToogleTitleClick = () => {
		const value = !hiddenControlPanel;
		setHiddenControlPanel( value );
	};

	const handleFixPanelHover = () => {
		// const value = !showControlPanel;
		if ( hiddenControlPanel && !showControlPanel ) {
			setShowControlPanel( true );
		} else {
			setShowControlPanel( false );
		}
	};

	const handleHiddenPanelLeave = () => {
		// console.log( '---- handleHiddenPanelLeave -----', dragging );
		if ( dragging ) return; //拖拽中不隐藏
		if ( hiddenControlPanel && showControlPanel ) {
			setShowControlPanel( false );
		}
	};

	//onMouseDown
	const onMouseDown = ( e: any ) => {
		console.log( '=== onMouseDown ====', e.pageX );
		if ( e.button !== 0 ) return; // 鼠标左键
		// dragging = true;
		setDragging( true );
		pos = {
			x: e.pageX,
			y: e.pageY,
			w: controlPanelWidth,
			dragging: true
		};

		document.onmouseup = onMouseUp;
		document.onmousemove = onMouseMove;

		e.stopPropagation();
		e.preventDefault();
	};

	//onMouseUp
	const onMouseUp = ( e: any ) => {
		console.log( '=== onMouseUp ====' );
		setDragging( false );
		pos.dragging = false;
		document.onmouseup = null;
		document.onmousemove = null;
		e.stopPropagation();
		e.preventDefault();
	};

	//onMouseMove
	const onMouseMove = ( e: any ) => {
		// console.log( '---- onMouseMove ----', e.pageX, pos.dragging );
		if ( !pos.dragging ) return;
		let width = pos.w + ( pos.x - e.pageX );
		width = width < 380 ? 380 : width; //最小宽度380
		setControlPanelWidth( width );
		e.stopPropagation();
		e.preventDefault();
	};

	const pageConf = pageContentConfig.page;

	const getStyle = () => {
		let imageStyle = '';
		if( !pageConf?.backgroundImageStyle || pageConf?.backgroundImageStyle === 1 ) {
			imageStyle = '0% 0% / 100% 100%';
		} else if( pageConf?.backgroundImageStyle === 2 ) {
			imageStyle = '0% 0% / 100%';
		} else if( pageConf?.backgroundImageStyle === 3 ) {
			imageStyle = '0% 0% / auto 100%';
		} else if( pageConf?.backgroundImageStyle === 4 ) {
			imageStyle = '0% 0% / auto';
		}



		let background = '#f0f3f4';
		if ( pageConf?.backgroundSetting === 3 ) {
			background = pageConf?.allBackgroundColor;
		} else {
			background = `${background} url('${pageConf?.backgroundImage && pageConf?.backgroundImage[0]?.url}') ${imageStyle}`;
		}

		return {
			background: background,
			filter: `blur(${pageConf?.bgImgBlur || 0}px)`,
			opacity: ( isNaN( pageConf?.bgImgOpacity ) ? 10 : pageConf.bgImgOpacity ) / 10
		};
	};

	//	初始化默认控制面板是编辑标题
	useEffect( () => {
		setCurrentType( pageContentConfig.page.type );
	}, [ setCurrentType, pageContentConfig.page.type ] );

	return (
		<div className={styles.editor_container}>
			<div className={styles.editor_top}>
				{props.isEdit ? (
					<EditorTop
						pageContentConfig={pageContentConfig}
						saveConfig={handelSaveConfig}
						publishConfig={props.publishConfig}
						addChart={addChart}
						pageType={props.pageType}
						pageId={pageId}
						pageInfo={props.pageInfo}
						reloadData={props.reloadData}
					></EditorTop>
				) : (
					<PreviewTop title={pageConf.name} isPublic={props.isPublic} pageId={pageId}></PreviewTop>
				)}
			</div>
			<div className={styles.editor_section}>
				<div
					id='editor_body'
					className={styles.editor_body}
				>
					{/* page区域，图表顶部 */}
					{ ( props.isEdit || pageConf?.showHeader !== false ) && (
						<Page
							config={pageConf}
							isCurrent={currentKey === pageConf.key}
							onSelect={( config ) => onSelect( config )}
						></Page>
					)}
					{/* 图表 */}
					<div className={styles.editor_body_content}>
						<div className={styles.editor_body_bg} style={ getStyle() }></div>
						<ChartsDragContainer
							handleCopyItem={( item ) => handleCopyItem( item )}
							isEdit={props.isEdit}
							chartsLayout={props.pageContentConfig.layoutConfig}
							currentKey={currentKey}
							chartsList={pageContentConfig.children}
							pageId={pageId}
							onSelect={onSelect}
							handleDelete={handleDelete}
							layoutConfChange={handleLayoutConfChange}
							onValuesChange={handelValuesChange}
							onAllValuesChange={handelAllValuesChange}
							tenantCode={tenantCode}
						></ChartsDragContainer>
					</div>
				</div>
				{props.isEdit && (
					<>
						{showControlPanel ? (
							<div
								className={hiddenControlPanel ? [ styles.fix, styles.editor_panel ].join( ' ' ) : styles.editor_panel}
								style={ { width: `${controlPanelWidth}px` } }
								onMouseLeave={handleHiddenPanelLeave}
							>
								<div className={styles.dragLine} onMouseDown={onMouseDown}></div>
								<div className={styles.editor_panel_title}>
									<div>控制面板</div>
									<div className={styles.editor_panel_title_btn} onClick={handleToogleTitleClick}>
										{hiddenControlPanel ? <DoubleLeftOutlined /> : <DoubleRightOutlined />}
									</div>
								</div>
								<div className={styles.editor_panel_content}>
									{ !isPage( currentType ) && (
										<EditorRight
											currentType={currentType}
											config={currentConf}
											allConfigs={pageContentConfig.children}
											pageId={pageId}
											pageConf={pageConf}
											onValuesChange={handelValuesChange}
											layoutConfig={props.pageContentConfig.layoutConfig}
											layoutConfChange={handleLayoutConfChange}
										></EditorRight>
									)}
									{ isPage( currentType ) && (
										<PageEditor
											config={pageConf}
											comps={pageContentConfig.children}
											onValuesChange={handelValuesChange}
											onAllValuesChange={handelAllValuesChange}
											key={pageId}
										></PageEditor>
									)}
								</div>
							</div>
						) : (
							<div onMouseOver={handleFixPanelHover} className={styles.editor_panel_title_fix}>
								<div>控制面板</div>
							</div>
						)}
						{
							hiddenControlPanel && (
								<div style={ { width: '50px' } }></div>
							)
						}
					</>
				)}
			</div>
		</div>
	);
};

export default React.memo( EditReportIndex );
